package com.protocols.sctp.m3ua.sccp.tcap;

import java.io.Serializable;
import java.math.BigInteger;
import java.util.ArrayList;

import com.protocols.BinaryInteger;
import com.protocols.GeneralProtocolData;
import com.protocols.OctaveInteger;
import com.protocols.ProtoOperations;
import com.protocols.ProtocolStackException;
import com.protocols.sctp.m3ua.sccp.SccpUnitDataMsg;

public class TcapConstructor extends TcapTag implements Serializable{


	private ArrayList<TcapTag> Constructor= new ArrayList<TcapTag>();
	private Boolean IsSet=false;
	public TcapConstructor() {
		
	}
	
	public TcapConstructor(int tag) {
		super(tag);
	}
	
	public byte [] getByteArray(){

		if (IsSet)
		{
			byte [] content=getContentBytes();
		
			return (content.length==0)?new byte[0]:ProtoOperations.concatArrays(super.getTagBytes(content.length),content);
		}
		else
			return new byte[0];
		
		
		
		
	}

	public void addElement(TcapTag element){
		
		Constructor.add(element);
		IsSet=true;
	}
	
	
	private byte [] getContentBytes(){
		byte [] content= new byte[0];		
		for (TcapTag element : Constructor) {
			
			if (element.getClass().getSimpleName().equals("TcapPrimitiveUnitString"))
			{
				content=ProtoOperations.concatArrays(content, ((TcapPrimitiveUnitString)element).getByteArray());
				
			}
			else if (element.getClass().getSimpleName().equals("TcapConstructor"))
			{
				content=ProtoOperations.concatArrays(content, ((TcapConstructor)element).getByteArray());
			}
			else if (element.getClass().getSimpleName().equals("TcapPrimitiveUnitByteArray"))
			{
				content=ProtoOperations.concatArrays(content, ((TcapPrimitiveUnitByteArray)element).getByteArray());
			}
			else if (element.getClass().getSimpleName().equals("TcapPrimitiveUnitNumber"))
			{
				content=ProtoOperations.concatArrays(content, ((TcapPrimitiveUnitNumber)element).getByteArray());
			}
			else if (element.getClass().getSimpleName().equals("TcapPrimitive7BitEncodedString"))
			{
				content=ProtoOperations.concatArrays(content, ((TcapPrimitive7BitEncodedString)element).getByteArray());
			}
		
			
		}
	
		return content;
		
	}
	
	
	public int getLength(){
		return getByteArray().length;
	}

	public int getContentLength(){
		return getContentBytes().length;
	}

	
	// recheck the set TAg Code method. when code >30 and when code > 1 Byte 

	

	// need to be tested
	public byte[] decode(byte[] input) throws ProtocolStackException {
			
		if (input.length==0)
			return input;
		
		int tagcode= input[0] & 0b00011111;
		int tagclass=(input[0] & 0b11000000)>>6;
		int tagform=(input[0] & 0b00100000)>>5;
		int lengthstart=1;		// Start of the Length
		if (tagcode==31){
			if ((input[1]&0xff)<128){
				tagcode=input[1]&0xff;
				lengthstart=2;
			}
			else{
				
				tagcode=(input[1]<<7) |input[2];
				lengthstart=3;
			}
		}
		
		int taglength=input[lengthstart]& 0xff;
		int noflengthoctets=0;
		if (taglength>128){
			noflengthoctets = input[lengthstart] & 0b01111111;
			taglength= ProtoOperations.intFromByteArray(input, lengthstart+1, noflengthoctets);
		}
		else{
			taglength= input[lengthstart]&0xff;
		}
		byte remainder[]=input; 
		if (this.getTagClass()==tagclass && this.getTagForm()==tagform && this.getTagCode()==tagcode){
			remainder =ProtoOperations.extractByteArray(input, lengthstart+noflengthoctets+1, input.length-(lengthstart+noflengthoctets+1));
			for (TcapTag element : Constructor) {
				remainder=element.decode(remainder);
			}
			
		}
		return remainder;
		
	}

	
	
	
	
}
